package com.ruoyi.common.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HTTPUtil {
    private static final int MAX_TOTAL_CONNECTIONS = 200;     // 最大连接数
    private static final int DEFAULT_MAX_PER_ROUTE = 50;      // 单路由最大连接数
    private static final int CONNECT_TIMEOUT = 5000;         // 连接超时（ms）
    private static final int SOCKET_TIMEOUT = 10000;          // 数据传输超时（ms）

    // 初始化连接池和 HttpClient
    private static final CloseableHttpClient httpClient;
    static {
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
        connManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        connManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);

        // 配置 SSL（忽略证书验证）
        SSLContext sslContext;
        try {
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
        } catch (Exception e) {
            throw new RuntimeException("SSL 上下文初始化失败", e);
        }
        HostnameVerifier allowAllHosts = (hostname, session) -> true;
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);

        // 构建全局 HttpClient
        httpClient = HttpClientBuilder.create()
                .setConnectionManager(connManager)
                .setSSLSocketFactory(sslSocketFactory)
                .setDefaultRequestConfig(RequestConfig.custom()
                        .setConnectTimeout(CONNECT_TIMEOUT)
                        .setSocketTimeout(SOCKET_TIMEOUT)
                        .build())
                .build();
    }

    /**
     * 发送 GET 请求
     * @param url 请求地址
     * @param params 查询参数（Map 形式）
     * @param headers 请求头（Map 形式）
     * @return 响应内容字符串
     */
    public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        HttpGet httpGet = new HttpGet(buildUrlWithParams(url, params));
        setHeaders(httpGet, headers);
        return executeRequest(httpGet);
    }

    /**
     * 发送 POST 请求（支持表单和 JSON）
     * @param url 请求地址
     * @param data 请求体数据（Map 或 JSON 字符串）
     * @param headers 请求头（需指定 Content-Type）
     */
    public static String post(String url, Object data, Map<String, String> headers) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        setHeaders(httpPost, headers);
        if (data instanceof Map) {
            httpPost.setEntity(new UrlEncodedFormEntity(convertMapToPairs((Map<String, String>) data), "UTF-8"));
        } else if (data instanceof String) {
            httpPost.setEntity(new StringEntity((String) data, "UTF-8"));
        }
        return executeRequest(httpPost);
    }

    // 工具方法：设置请求头
    private static void setHeaders(HttpRequestBase request, Map<String, String> headers) {
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                request.addHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    // 工具方法：执行请求并处理响应
    private static String executeRequest(HttpRequestBase request) throws IOException {
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            HttpEntity entity = response.getEntity();
            return entity != null ? EntityUtils.toString(entity, "UTF-8") : null;
        }
    }

    // 工具方法：构建带参数的 URL
    private static String buildUrlWithParams(String url, Map<String, String> params) {
        if (params == null || params.isEmpty()) return url;
        StringBuilder urlBuilder = new StringBuilder(url).append("?");
        params.forEach((k, v) -> urlBuilder.append(k).append("=").append(v).append("&"));
        return urlBuilder.deleteCharAt(urlBuilder.length() - 1).toString();
    }

    // 工具方法：将 Map 转换为 NameValuePair 列表
    private static List<NameValuePair> convertMapToPairs(Map<String, String> data) {
        List<NameValuePair> pairs = new ArrayList<>();
        data.forEach((k, v) -> pairs.add(new BasicNameValuePair(k, v)));
        return pairs;
    }
}
